package is.web.xdumper.client;

import is.bean.entity.xdumper.session.Action;
import is.xdumper.XdumperNoPathException;
import is.web.xdumper.client.table.XdumperRewriteTable;
import is.xdumper.type.Entity;
import is.xdumper.type.ValidatorResultContainer;
import java.io.*;
import java.rmi.RemoteException;
import java.util.List;
import javax.ejb.CreateException;
import javax.ejb.FinderException;
import javax.naming.NamingException;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.xml.sax.SAXException;

/**
 * Holds wizard step-by-step logic.
 *
 * @author aspr0
 */
public class XdumperClient extends XdumperClientRoutines
{
    public XdumperClient() throws CreateException, RemoteException, NamingException
    {
        super();
    }

    /**
     * Steps through preparing dump using POST parameters incoming from web page via
     * <code>request</code>.
     * Generates HTML for wizard pages.
     *
     * @return
     */
    public String stepImport() throws NamingException, RemoteException, CreateException,
                                      IOException,
                                      FileUploadException, ClassNotFoundException, XdumperNoPathException,
                                      FinderException
    {
        XdumperHtml h = new XdumperHtml();
        String advice;
        String form;

        /* == import branch == */
        /* import result (2nd) */
        // apache file uploads conflicts with getParameter so placed behind such calls
        //todo костыль!
        if (ServletFileUpload.isMultipartContent(request))
        {
            ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
            List<FileItem> fileItems = upload.parseRequest(this.request);
            String dumpXml = fileItems.get(0).getString();

            try
            {
                ValidatorResultContainer resultContainer = xdumper.validateImport(dumpXml);

                switch (resultContainer.getResult())
                {
                    case IMPORT_READY:
                    {
                        int sid = clientSession.startSession(Action.IMPORT);

                        xdumper.doImport(resultContainer.getDump());

                        advice = String.format(h.ADVICE_CANVAS, h.ADVICE[10]);
                        String inputSubmit = String.format(h.DIV_ACTION_INPUT, h.INPUT_SUBMIT_FINISH);
                        form = String.format(h.FORM_DIV_ACTION, inputSubmit);

                        clientSession.endSession(sid, saveImportFile(dumpXml));
                    }
                    break;

                    case NEED_REWRITE:
                    {
                        int sid = clientSession.startSession(Action.IMPORT);

                        /* Dumps serialize to restore in next step */
                        String fileName = String.format("%s.dump.tmp", getDateString());
                        String fileNameR = String.format("%s.dump-rewrite.tmp", getDateString());
                        dump = resultContainer.getDump();
                        dumpRewrite = resultContainer.getDumpRewrite();
                        serializeDumps(fileName, fileNameR);

                        advice = String.format(h.ADVICE_CANVAS, h.ADVICE[9]);
                        String tableRewrite = XdumperRewriteTable.generate(resultContainer.getDump(),
                                                                           resultContainer.getDumpRewrite());
                        String inputHidden = String.format(h.INPUT_HIDDEN, "step", "importRewrite")
                                + String.format(h.INPUT_HIDDEN, "sid", sid)
                                + String.format(h.INPUT_HIDDEN, "dumpFileName", saveImportFile(dumpXml))
                                + String.format(h.INPUT_HIDDEN, "tmpFile", fileName)
                                + String.format(h.INPUT_HIDDEN, "tmpFileR", fileNameR);
                        String inputSubmit = String.format(h.DIV_ACTION_INPUT,
                                                           h.INPUT_SUBMIT_CANCEL + h.INPUT_SUBMIT_IMPORT);
                        form = String.format(h.FORM_DIV_ACTION, tableRewrite + inputHidden + inputSubmit);
                    }
                    break;

                    case REFS_INVALID:
                    {
                        advice = String.format(h.ADVICE_CANVAS, h.ADVICE[8]);
                        String inputSubmit = String.format(h.DIV_ACTION_INPUT, h.INPUT_SUBMIT_FINISH);
                        form = String.format(h.FORM_DIV_ACTION, inputSubmit);
                    }
                    break;

                    default:
                        throw new RuntimeException("shit happens. result not set");
                }
            }
            catch (SAXException ex)
            {
                /* File format is incorrect, you could not pass */
                advice = String.format(h.ADVICE_CANVAS, h.ADVICE[7]);
                String inputSubmit = String.format(h.DIV_ACTION_INPUT, h.INPUT_SUBMIT_FINISH);
                form = String.format(h.FORM_DIV_ACTION, inputSubmit);
            }
        }
        /* import rewrite (3rd) */
        //todo on rewrite old foreign keys may voilate - control it
        else if ((paramEquals("step", "importRewrite") && paramEquals("submit", "Import")))
        {
            unserializeDumps(request.getParameter("tmpFile"), request.getParameter("tmpFileR"));
            collectRewriteItems();

            xdumper.doImport(dump);

            advice = String.format(h.ADVICE_CANVAS, h.ADVICE[10]);
            String inputSubmit = String.format(h.DIV_ACTION_INPUT, h.INPUT_SUBMIT_FINISH);
            form = String.format(h.FORM_DIV_ACTION, inputSubmit);

            clientSession.endSession(
                    Integer.parseInt(request.getParameter("sid")),
                    request.getParameter("dumpFileName"));
        }
        /* import file (1st) */
        else
        {
            advice = String.format(h.ADVICE_CANVAS, h.ADVICE[6]);

            String inputFile = String.format(h.DIV_ACTION_INPUT, h.INPUT_FILE);
            String inputHidden = String.format(h.INPUT_HIDDEN, "step", "importFile");
            String inputSubmit = String.format(h.DIV_ACTION_INPUT, h.INPUT_SUBMIT_CANCEL_JS + h.INPUT_SUBMIT_NEXT);

            form = String.format(h.FORM_MULTIPART_DIV_ACTION, inputFile + inputHidden + inputSubmit);
        }

        return advice + form;
    }

    public String doExport(Entity majorEntity) throws XdumperNoDumpItemsException, NamingException, RemoteException,
                                                      XdumperNoPathException, CreateException, FinderException
    {
        int sid = clientSession.startSession(Action.EXPORT);

        dump.setMajorEntity(majorEntity);
        dump.setDumpReferences(getDumpReferences());

        collectDumpItems();

        String dumpFileName = String.format("isbdx-dump.%s.%s.xml", majorEntity.toString(), getDateString());

        String dumpFilePath = XdumperClientConf.getPathOutputDir() + dumpFileName;
        String dumpLink = String.format("<a href=\"%s\" target=\"_blank\">%s</a> <img src=\"../img/extlink.png\">",
                                        XdumperClientConf.PATH_DUMP_WEB + dumpFileName,
                                        dumpFileName);

        xdumper.doExport(dump, new File(dumpFilePath));

        clientSession.endSession(sid, dumpFileName);

        return dumpLink;
    }
}
